# -*- coding: utf-8 -*-
#coding=utf-8

import web
import json

from action.ajax.base import ajaxAction
from log import log
from config import COUNT_PER_PAGE
from model.user import user
from model.category import category as modelCategory
from model.product import product as modelProduct
from model.company import company as modelCompany
from model.prodcomment import prodcomment as modelProdcomment
from model.favorite import favorite as modelFavorite
from model.about import about as modelAbout
from model.image import image as modelImage
from model.news import news as modelNews
from model.info import info as modelInfo

'''
Ajax Actions: post and get ajax actions
'''
class actions(ajaxAction):
    def __init__(self, name = 'actions'):
        ajaxAction.__init__(self, name)

    def GET(self, name):
        if name == 'profile':
            return self.profile()
        elif name == 'newscats':
            return self.newscats()
        elif name == 'prodcats':
            return self.prodcats()
        elif name == 'companycats':
            return self.companycats()
        elif name == 'infocats':
            return self.infocats()
        elif name == 'products':
            return self.products()
        elif name == 'companyprods':
            return self.companyprods()
        elif name == 'myprodfavors':
            return self.myprodfavors()
        elif name == 'prodcomments':
            return self.prodcomments()
        elif name == 'myprodcomments':
            return self.myprodcomments()
        elif name == 'product':
            return self.product()
        elif name == 'search':
            return self.search()
        elif name == 'swipeshow':
            return self.swipeshow()
        elif name == 'newslist':
            return self.newslist()
        elif name == 'newscontent':
            return self.newscontent()
        elif name == 'infolist':
            return self.infolist()
        elif name == 'infocontent':
            return self.infocontent()
        elif name == 'about':
            return self.about()
        elif name == 'companies':
            return self.companies()
        elif name == 'company':
            return self.company()
        elif name == 'sysnews':
            return self.sysnews()

        return self.notFound()

    def POST(self, name): 
        if name == 'login':
            return self.login()
        elif name == 'logout':
            return self.logout()
        elif name == 'check':
            return self.check()
        elif name == 'register':
            return self.register()
        elif name == 'modprofile':
            return self.modprofile()
        elif name == 'publishcmt':
            return self.publishcmt()
        elif name == 'addprodfavor':
            return self.addprodfavor()

        return self.notFound()

    def sysnews(self):
        try:
            news = modelNews().getOne("id, name, content", {'category': 1})
            if not news:
                news = {'id': '', 'name': '', 'content':''}
            return json.dumps(news)
        except Exception, e:
            log.warn(e)
            return self.error()

    def about(self):
        aboutObj = modelAbout().getOne('*',{})
        return json.dumps(aboutObj)

    def companies(self):
        inputs = self.getInput()
        try:
            offset = int(inputs['offset']) if inputs.has_key('offset') else 0
            limit = int(inputs['limit']) if inputs.has_key('limit') else COUNT_PER_PAGE
            action = inputs['action'] if inputs.has_key('action') else 'default'

            if action == "up":
                condition = 'category>1 AND id<%d' % offset
            else:
                condition = 'category>1 AND id>%d' % offset

            companies = modelCompany().getList("id, name, desc, logo, category",
                                           condition,
                                           orders="id desc",
                                           limits=str(limit))
            for company in companies:
                company['logo'] = self.imageBlob(company['logo'])
                company['desc'] = self.subText(self.htmlunquote(company['desc']), 0, 32)

            return json.dumps(companies)
        except Exception, e:
            log.warn(e)
            return self.error()

    def newscats(self):
        try:
            newslist = modelNews().getList('id,category', 'category>1')
            ids = list()
            for news in newslist:
                ids.append(news['category'])

            categories = list()
            for id in ids:
                category = modelCategory().getOne('*', {'id': id})
                categories.append(category)

            return json.dumps(categories)
        except Exception, e:
            log.warn(e)
            return self.error()

    def infocats(self):
        try:
            infolist = modelInfo().getList('id,category', 'category>1')
            ids = list()
            for info in infolist:
                ids.append(info['category'])

            categories = list()
            for id in ids:
                category = modelCategory().getOne('*', {'id': id})
                categories.append(category)

            return json.dumps(categories)
        except Exception, e:
            log.warn(e)
            return self.error()

    def prodcats(self):
        try:
            prodlist = modelProduct().getList('id,category', 'category>1')
            ids = list()
            for prod in prodlist:
                ids.append(prod['category'])

            categories = list()
            for id in ids:
                category = modelCategory().getOne('*', {'id': id})
                categories.append(category)

            return json.dumps(categories)
        except Exception, e:
            log.warn(e)
            return self.error()

    def companycats(self):
        try:
            companies = modelCompany().getList('id,category','category>1')
            ids = list()
            for company in companies:
                ids.append(company['category'])

            categories = list()
            for id in ids:
                category = modelCategory().getOne('*', {'id': id})
                categories.append(category)

            return json.dumps(categories)
        except Exception, e:
            log.warn(e)
            return self.error()


    def newslist(self):
        inputs = self.getInput()
        try:
            offset = int(inputs['offset']) if inputs.has_key('offset') else 0
            limit = int(inputs['limit']) if inputs.has_key('limit') else COUNT_PER_PAGE
            action = inputs['action'] if inputs.has_key('action') else 'default'

            if action == "up":
                condition = 'category>1 AND id<%d' % offset
            else:
                condition = 'category>1 AND id>%d' % offset

            newslist = modelNews().getList("id, name, desc, thumbnail, category",
                                           condition,
                                           orders="id desc",
                                           limits=str(limit))
            for news in newslist:
                news['thumbnail'] = self.imageBlob(news['thumbnail'])
                news['desc'] = self.subText(self.htmlunquote(news['desc']), 0, 32)

            return json.dumps(newslist)
        except Exception, e:
            log.warn(e)
            return self.error()

    def newscontent(self):
        inputs = self.getInput()
        try:
            if not inputs.has_key('id'):
                return self.error()

            news = modelNews().getOne("id, name, content", {'id': inputs['id']})
            return json.dumps(news)
        except Exception, e:
            log.warn(e)
            return self.error()

    def infolist(self):
        inputs = self.getInput()
        try:
            category = int(inputs['category']) if inputs.has_key('category') else 0
            offset = int(inputs['offset']) if inputs.has_key('offset') else 0
            limit = int(inputs['limit']) if inputs.has_key('limit') else COUNT_PER_PAGE
            action = inputs['action'] if inputs.has_key('action') else 'default'

            if action == "up":
                condition = 'category=%d AND id<%d' % (category, offset)
            else:
                condition = 'category=%d AND id>%d' % (category, offset)

            infolist = modelInfo().getList("id, name, desc, thumbnail, category",
                                           condition,
                                           orders="id desc",
                                           limits=str(limit))
            for info in infolist:
                info['thumbnail'] = self.imageBlob(info['thumbnail'])
                info['desc'] = self.subText(self.htmlunquote(info['desc']), 0, 32)

            return json.dumps(infolist)
        except Exception, e:
            log.warn(e)
            return self.error()

    def infocontent(self):
        inputs = self.getInput()
        try:
            if not inputs.has_key('id'):
                return self.error()

            info = modelInfo().getOne("id, name, content", {'id': inputs['id']})
            return json.dumps(info)
        except Exception, e:
            log.warn(e)
            return self.error()

    def products(self):
        inputs = self.getInput()
        try:
            category = inputs['category'] if inputs.has_key('category') else -1
            limit = inputs['limit'] if inputs.has_key('limit') else COUNT_PER_PAGE
            offset = inputs['offset'] if inputs.has_key('offset') else 0
            action = inputs['action'] if inputs.has_key('action') else 'default'

            if action == 'down':
                condition = 'category=%d AND id>%d' % (int(category), int(offset))
            elif action == 'up':
                condition = 'category=%d AND id<%d' % (int(category), int(offset))
            else:
                condition = {'category': category}

            items = modelProduct().getList('id,picture,desc,name', condition, orders="id desc", limits=str(limit))
            for item in items:
                item['thumbnail'] = self.imageBlob(item['picture'])
                item['desc'] = self.subText(self.htmlunquote(item['desc']), 0, 32)

            return json.dumps(items)
        except Exception, e:
            log.warn(e)
            return self.error()

    def companyprods(self):
        inputs = self.getInput()
        try:
            company = inputs['company'] if inputs.has_key('company') else -1
            limit = inputs['limit'] if inputs.has_key('limit') else COUNT_PER_PAGE
            offset = inputs['offset'] if inputs.has_key('offset') else 0
            action = inputs['action'] if inputs.has_key('action') else 'default'

            if action == 'down':
                condition = 'company=%d AND id>%d' % (int(company), int(offset))
            elif action == 'up':
                condition = 'company=%d AND id<%d' % (int(company), int(offset))
            else:
                condition = {'company': company}

            items = modelProduct().getList('id,picture,desc,name', condition, orders="id desc", limits=str(limit))
            for item in items:
                item['thumbnail'] = self.imageBlob(item['picture'])
                item['desc'] = self.subText(self.htmlunquote(item['desc']), 0, 32)

            return json.dumps(items)
        except Exception, e:
            log.warn(e)
            return self.error()



    def myprodcomments(self):
        username = self.isLogin()
        if not username or username == 'admin':
            log.warn('Login required!')
            return self.unauthorized()

        try:
            inputs = self.getInput()
            limit = int(inputs['limit']) if inputs.has_key('limit') else COUNT_PER_PAGE
            offset = int(inputs['offset']) if inputs.has_key('offset') else 0
            action = inputs['action'] if inputs.has_key('action') else 'default'

            # try to retrieve user id by userame
            userObj = user().getOne('id,nickname', {'email': username})
            condition = 'user=%d' % userObj['id']

            # pull down or pull up?
            if action == 'down':
                condition += ' AND id>%d ' % offset
            elif action == 'up':
                condition += ' AND id<%d ' % offset

            items = modelProdcomment().getList('*', condition, orders="id desc", limits=str(limit))
            for item in items:
                item['createTime' ] = item['createTime'].split(' ')[0]
                item['nickname'] = userObj['nickname']

            return json.dumps(items)
        except Exception, e:
            log.warn(e)
            return self.error()

    def prodcomments(self):
        try:
            inputs = self.getInput()
            product = int(inputs['product']) if inputs.has_key('product') else -1
            limit = int(inputs['limit']) if inputs.has_key('limit') else COUNT_PER_PAGE
            offset = int(inputs['offset']) if inputs.has_key('offset') else 0
            action = inputs['action'] if inputs.has_key('action') else 'default'

            condition = 'product=%d' % product
            # pull down or pull up?
            if action == 'down':
                condition += ' AND id>%d ' % offset
            elif action == 'up':
                condition += ' AND id<%d ' % offset

            items = modelProdcomment().getList('*', condition, orders="id desc", limits=str(limit))
            for item in items:
                item['createTime' ] = item['createTime'].split(' ')[0]
                item['nickname'] = user().getOne('nickname', {'id': item['user']})['nickname']

            return json.dumps(items)
        except Exception, e:
            log.warn(e)
            return self.error()


    def myprodfavors(self):
        username = self.isLogin()
        if not username or username == 'admin':
            log.warn('Login required!')
            return self.unauthorized()

        try:
            # retrieve user id by username
            uid = user().getOne('id', {'email': username})['id']

            inputs = self.getInput()
            limit = int(inputs['limit']) if inputs.has_key('limit') else COUNT_PER_PAGE
            offset = int(inputs['offset']) if inputs.has_key('offset') else 0
            action = inputs['action'] if inputs.has_key('action') else 'default'

            condition = 'user=%d' % uid

            if action == 'down':
                condition += ' AND id>%d ' % offset
            elif action == 'up':
                condition += ' AND id<%d ' % offset

            items = modelFavorite().getList('product', condition, orders="id desc", limits=str(limit))
            products = []

            for item in items:
                product = modelProduct().getOne('id,picture,name,desc', {'id': item['product']})
                product['thumbnail'] = self.imageBlob(product['picture'])
                product['desc'] = self.subText(self.htmlunquote(product['desc']), 0, 32)
                products.append(product)

            return json.dumps(products)
        except Exception, e:
            log.warn(e)
            return self.error()

    def product(self):
        try:
            inputs = self.getInput()
            if not inputs.has_key('id'):
                log.warn('product id not provided!')
                return self.error()

            prod = modelProduct().getOne('*', {'id': inputs['id']})
            if prod:
                prod['picture'] = self.imageUrl(prod['picture'])

            return json.dumps(prod)
        except Exception, e:
            log.warn(e)
            return self.error()

    def company(self):
        try:
            inputs = self.getInput()
            if not inputs.has_key('id'):
                log.warn('company id not provided!')
                return self.error()

            company = modelCompany().getOne('*', {'id': inputs['id']})
            return json.dumps(company)
        except Exception, e:
            log.warn(e)
            return self.error()

    def search(self):
        inputs = self.getInput()
        try:
            keywords = inputs['keywords'].strip().lower() if inputs.has_key('keywords') else ''
            limit = inputs['limit'] if inputs.has_key('limit') else COUNT_PER_PAGE
            offset = inputs['offset'] if inputs.has_key('offset') else 0
            action = inputs['action'] if inputs.has_key('action') else 'default'
            category = inputs['category'] if inputs.has_key('category') else -1

            # workarond against search view, which always send keywords to the backend
            condition = 'lower(name) like \'%' + keywords +'%\' AND ' if keywords and keywords != 'null' else ''

            if action == 'down':
                condition += 'category=%d AND id>%d' % (int(category), int(offset))
            elif action == 'up':
                condition += 'category=%d AND id<%d' % (int(category), int(offset))
            else:
                condition += 'category=%d' % int(category)

            products = modelProduct().getList('*', condition, orders="id desc")
            for product in products:
                product['desc'] = self.subText(self.htmlunquote(product['desc']), 0, 32)
                product['thumbnail'] = self.imageBlob(product['picture'])

            return json.dumps(products)
        except Exception, e:
            log.warn(e)
            return self.error()

    def swipeshow(self):
        images = modelImage().getList('id,ref,desc', {'album': 2})
        for image in images:
            image['url'] = self.imageUrl(image['id'])

        return json.dumps(images)

    def login(self):
        from hashlib import md5
        inputs = self.getInput()

        condition = {'email': inputs['email']}
        userObj = user().getOne('passwd, nickname', condition)
        password = md5(inputs['password']).hexdigest()
        if not userObj or password != userObj['passwd']:
            log.warn('Login validation fails: %s' % inputs['email'])
            return self.error()

        self.setLogin(inputs['email'])
        return self.success()

    def logout(self):
        username = self.isLogin()
        if not username or username == 'admin':
            log.warn('Login required!')
            return self.unauthorized()

        self.setLogin()
        return self.success()

    def check(self):
        username = self.isLogin()
        if not username or username == 'admin':
            log.warn('Login required!')
            return self.unauthorized()

        return self.success()
        
    def publishcmt(self):
        username = self.isLogin()
        if not username or username == 'admin':
            return self.unauthorized()

        try:
            # retrieve inputs
            inputs = self.getInput()
            content = inputs['content'] if inputs.has_key('content') else ''
            rank = inputs['rank'] if inputs.has_key('rank') else 0
            product = inputs['product']

            # retrieve user id by username
            userid = user().getOne('id', {'email': username})['id']

            # insert to db
            modelProdcomment().insert({'user': userid, 'product': product, 'rank': rank, 'content': content})
        except Exception, e:
            log.warn(e)
            return self.error()

        return self.success()

    def addprodfavor(self):
        username = self.isLogin()
        if not username or username == 'admin':
            return self.unauthorized()

        try:
            # retrieve inputs
            inputs = self.getInput()
            product = inputs['product']

            # retrieve user id by username
            userid = user().getOne('id', {'email': username})['id']

            # validate whether this is already been added
            if not modelFavorite().getOne('*', {'user': userid, 'product': product}):
                modelFavorite().insert({'user': userid, 'product': product})
        except Exception, e:
            log.warn(e)
            return self.error()

        return self.success()

    def profile(self):
        username = self.isLogin()
        if not username or username == 'admin':
            log.warn('Login required!')
            return self.unauthorized()

        condition = {'email': username}
        userObj = user().getOne('*', condition)
        if not userObj:
            return self.error()

        userObj['avatur'] = self.imageUrl(userObj['avatur'])
        return json.dumps(userObj)

    def register(self):
        from hashlib import md5
        inputs = self.getInput()
        try:
            data = {
                'nickname'  :   inputs['nickname'],
                'email'     :   inputs['email'],
                'passwd'    :   md5(inputs['password']).hexdigest(),
             }

            user().insert(data)
        except Exception, e:
            log.warn(e)
            return self.error()

        self.setLogin(inputs['email'])
        return self.success()

    def modprofile(self):
        username = self.isLogin()
        if not username or username == 'admin':
            log.warn('Login required!')
            return self.unauthorized()

        from hashlib import md5
        inputs = self.getInput()
        try:
            data = {
                'nickname'  :   inputs['nickname'],
                'name'      :   inputs['name'],
                'gender'    :   int(inputs['gender']),
                'phoneno'   :   inputs['phoneno'],
                'address'   :   inputs['address'],
                'passwd'    :   md5(inputs['password']).hexdigest(),
             }

            user().update(data, {'email': username})
        except Exception, e:
            log.warn(e)
            return self.error()

        return self.success()
